package com.unbox.admin.controller;

import com.unbox.admin.entity.Menu;
import com.unbox.admin.entity.UserRoles;
import com.unbox.admin.fegin.MenuFegin;
import com.unbox.admin.service.IMenuService;
import com.unbox.admin.service.IRoleMenuService;
import com.unbox.admin.service.IUserRolesService;
import com.unbox.common.response.UnboxResponse;
import com.unbox.common.table.UnBoxPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * <菜单管理业务Controller
 * </p>
 *
 * @author 王振宇
 * @since 2021-03-04
 */
@Api(tags = "菜单管理管理api")
@RestController
public class MenuController implements MenuFegin {

    @Autowired
    IMenuService menuService;

    @Autowired
    IRoleMenuService roleMenuService;

    @Autowired
    IUserRolesService iUserRolesService;

    /**
     * 分页查询
     * @param menu
     * @return
     */
    @ApiOperation(value = "分页查询列表")
    @Override
    public UnboxResponse<UnBoxPage> getPageList(Menu menu, Integer pageNo, Integer pageSize) {
        UnBoxPage page = menuService.getPageList(menu,pageNo, pageSize);
        return new UnboxResponse<>(page);
    }

    /**
     * 分页查询
     * @param menu
     * @return
     */
    @ApiOperation(value = "查询列表")
    @Override
    public UnboxResponse<List<Menu>> getList(Menu menu) {
        List<Menu> menuList = menuService.getList(menu);
        List<Menu> pmenuList = getMenuList(menuList);
        return new UnboxResponse<>(pmenuList);
    }

    /**
     * 详情
     * @param menu
     * @return
     */
    @ApiOperation(value = "查询明细")
    @Override
    public UnboxResponse<Menu> info(Menu menu) {
        Menu menuVo = menuService.get(menu);
        return new UnboxResponse<>(menuVo);
    }

    /**
     * 通过id数据查询数据
     * @param ids
     * @return
     */
    @ApiOperation(value = "通过ids进行in查询")
    @Override
    public UnboxResponse<List<Menu>> idsMenus(List<Integer> ids) {
        List<Menu> menus = menuService.getIdsList(ids);
        return new UnboxResponse<>(menus);
    }

    /**
     * 保存数据
     * @param menu
     * @return
     */
    @ApiOperation(value = "保存数据")
    @Override
    public UnboxResponse<Boolean> save(Menu menu) {
        Boolean flg = menuService.save(menu);
        return new UnboxResponse<>(flg);
    }

    /**
     * 批量添加
     * @param menus
     * @return
     */
    @ApiOperation(value = "批量保存数据")
    @Override
    public UnboxResponse<Boolean> batchSave(List<Menu> menus) {
        Boolean flg = menuService.saveBatch(menus);
        return new UnboxResponse<>(flg);
    }

    /**
     * 修改数据
     * @param menu
     * @return
     */
    @ApiOperation(value = "修改数据")
    @Override
    public UnboxResponse<Boolean> update(Menu menu) {
        Boolean flg = menuService.update(menu);
        return new UnboxResponse<>(flg);
    }

    /**
     * 批量修改
     * @param menus
     * @return
     */
    @ApiOperation(value = "批量修改数据")
    @Override
    public UnboxResponse<Boolean> batchUpdate(List<Menu> menus) {
        Boolean flg = menuService.updateBatchById(menus);
        return new UnboxResponse<>(flg);
    }

    /**
     * 删除数据
     * @param menu
     * @return
     */
    @ApiOperation(value = "删除数据")
    @Override
    public UnboxResponse<Boolean> delete(Menu menu) {
        Boolean flg = menuService.remove(menu);
        return new UnboxResponse<>(flg);
    }

    /**
     * 批量删除
     * @param ids
     * @return
     */
    @ApiOperation(value = "批量删除")
    @Override
    public UnboxResponse<Boolean> deleteBatch(List<Integer> ids) {
        Boolean flg = menuService.removeByIds(ids);
        return new UnboxResponse<>(flg);
    }

    /**
     * 获取个人菜单
     * @param userId
     * @return
     */
    @Override
    public UnboxResponse<List<Menu>> getUserMenuList(@RequestParam(value = "userId") Integer userId) {

        // 获取个人权限分配
        UserRoles roles = new UserRoles();
        roles.setUserId(userId);
        List<UserRoles> userRoles = iUserRolesService.getList(roles);

        // 筛选角色id
        List<Integer> roleIds = userRoles.stream()
                .map(role -> role.getRoleId())
                .collect(Collectors.toList());

        // 获取菜单id
        List<Integer> menuIds = roleMenuService.getRoleIdsList(roleIds)
                .stream()
                .map(menu -> menu.getMenuId())
                .collect(Collectors.toList());

        // 获取菜单列表
        List<Menu> menus = menuService.getIdsList(menuIds);

        // 筛选夫级别菜单id
        List<Integer> fuMenusIds = menus.stream()
                .filter(menu -> menu.getType().equals(2))
                .map(menu -> menu.getPid())
                .distinct()
                .collect(Collectors.toList());
        menuIds.addAll(fuMenusIds);

        // 获取二级目录
        menus = menuService.getIdsList(fuMenusIds);
        fuMenusIds = menus.stream()
                .filter(menu -> menu.getType().equals(1))
                .map(menu -> menu.getPid())
                .distinct()
                .collect(Collectors.toList());

        menuIds.addAll(fuMenusIds);
        menus = menuService.getIdsList(menuIds);
        List<Menu> pmenuList = getMenuList(menus);
        return new UnboxResponse<>(pmenuList);
    }

    /**
     * 组装列表
     * @param menus
     * @return
     */
    private List<Menu> getMenuList(List<Menu> menus) {
        // 获取根菜单
        List<Menu> pmenuList = menus.stream()
                .filter(menuVo -> menuVo.getType() == 0)
                .collect(Collectors.toList());

        // 拼接2层3层
        pmenuList.forEach(menuVo -> {
            menuVo.setLayer(1);

            // 获取二层菜单
            List<Menu> resultList = menus.stream()
                    .filter(menu1 -> menuVo.getMenuId().equals(menu1.getPid()))
                    .collect(Collectors.toList());

            // 获取三层菜单
            resultList.forEach(menu2 -> {
                menu2.setLayer(2);
                List<Menu> menu3ResultList = menus.stream()
                        .filter(menu3 -> menu2.getMenuId().equals(menu3.getPid()))
                        .collect(Collectors.toList());
                menu2.setChildren(menu3ResultList);
            });
            menuVo.setChildren(resultList);
        });
        return pmenuList;
    }
}

